from mod_pywebsocket import msgutil

import thread
import getopt
import os
import sys
import time
import socket
import struct

_HEARTBEAT_ = 'Heartbeat'
_CONNECTING_ = 0
_OPEN_ = 1
_CLOSING_ = 2
_CLOSE_ = 3

MCAST_GRP = '224.0.2.1'
MCAST_PORT = 15011



_status_ = _CONNECTING_

class mcast:
	def __init__(self, req):
		
		self.req = req
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
		self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		if hasattr(socket, 'SO_REUSEPORT'):
			self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
		self.sock.bind(('', MCAST_PORT))
		mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)

		self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)


	def run(self):
		global _status_
		while True:
			if _status_ != _OPEN_:
				_status_ = _CLOSE_
				break
			line = self.sock.recv(10240)
			msgutil.send_message(self.req, line.decode('utf-8'))



def web_socket_do_extra_handshake(request):
	pass  # Always accept.


def web_socket_transfer_data(request):
	global _status_
	_status_ = _OPEN_
	arr = ()
	thread.start_new_thread(mcast(request).run, arr)

#	sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
#	sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 0)
#	sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)
	while True:
		try:
			#######################################################
			# Note::
			# mesgutil.receive_message() returns 'unicode', so
			# if you want to treated as 'string', use encode('utf-8')
			#######################################################
			line = msgutil.receive_message(request).encode('utf-8')
			
			if line == _HEARTBEAT_:
				continue
		
			#sock.sendto(line, (MCAST_GRP, MCAST_PORT))
			
		except Exception:
			_status_ = _CLOSING_
			# wait until _status_ change.
			i = 0
			while _status_ == _CLOSING_:
				time.sleep(0.5)
				i += 1
				if i > 10:
					break
			return
